package com.java.simple.study.juc.p5;

import com.java.simple.study.tool.Sleeper;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * @author zhoujunlin
 * @date 2022年07月01日 21:45
 * @desc 22:01:33.122 c.ABAStampedRef [main] - main start...
 * 22:01:33.122 c.ABAStampedRef [main] - 值：A, 版本号：0
 * 22:01:33.153 c.ABAStampedRef [t1] - change A->B true
 * 22:01:34.169 c.ABAStampedRef [t2] - change B->A true
 * 22:01:36.169 c.ABAStampedRef [main] - change A ->C false
 */
@Slf4j(topic = "c.ABAStampedRef")
public class ABAStampedRef {

    /**
     * 初始值+版本号
     */
    static AtomicStampedReference<String> ref = new AtomicStampedReference<>("A", 0);

    public static void main(String[] args) {
        log.debug("main start...");
        // 获取值A
        String mainPrev = ref.getReference();
        // 获取版本号
        int mainStamp = ref.getStamp();
        log.debug("值：{}, 版本号：{}", mainPrev, mainStamp);
        // A->B   B->A
        other();
        Sleeper.sleep(2);
        // 尝试修改为C且版本号+1
        log.debug("change A ->C {}", ref.compareAndSet(mainPrev, "C", mainStamp, ++mainStamp));
    }

    private static void other() {
        new Thread(() -> {
            log.debug("change A->B {}", ref.compareAndSet(ref.getReference(), "B", ref.getStamp(), ref.getStamp() + 1));
        }, "t1").start();
        Sleeper.sleep(1);
        new Thread(() -> {
            log.debug("change B->A {}", ref.compareAndSet(ref.getReference(), "A", ref.getStamp(), ref.getStamp() + 1));
        }, "t2").start();
    }


}
